﻿using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Windows.Forms;
using ApplicationLibrary;
using ApplicationLibrary.CounterManager;
using ApplicationLibrary.DBManager;
using ApplicationLibrary.ExtendedControls;
using ApplicationLibrary.SqlConnector;
using Vintner.Items.ModuleData;
using Vintner.Library;
using Vintner.Masters.ModuleData;
using Vintner.Sales.DataSet;
using Vintner.Sales.ModuleData;
using Vintner.Sales.Reports;

namespace Vintner.Sales.Forms
{
    public partial class SaleInvoices : DocumentForm
    {
        private const string PRINT_INVOICE = "PRINT_INVOICE";
        private const string DELETE_INVOICE = "DELETE_INVOICE";
        private CounterFormatter formatter = null;
        private DRCustomer dRCustomer = null;
        private DRItemsPrice dRItemsPrice = null;
        private RRItemCustomerPrice rRItemCustomerPrice = null;
        private DRItemCustomerPrice dRItemCustomerPrice = null;
        private RRItemCategory rrItemCat = null;
        private DRItems drItems = null;
        private DRTaxCode drTaxCode = null;
        private DRDescriptions drCategories = null;
        private ComboBoxManager<string> cbbTransportManager = null;
        private ComboBoxManager<string> cbbPaymentManager = null;
        private TotalTaxable totals = new TotalTaxable();

        protected BindableOject<bool> IsDado = new BindableOject<bool>();
        protected bool isDado = false;

        public ApplicationLibrary.ExtendedControls.TabControl MasterTabControl { get { return tabControl1; } }

        public SaleInvoices()
            : base("SaleInvoices")
        {
            InitializeComponent();
            keyControl = fncSalesNo;
        }

        #region Virtual Method

        protected override IRadarParameters GetKeyFromDocument()
        {
            return new RadarSaleInvoicesParam(fncSalesNo.Text);
        }

        protected override void OnAttachData()
        {
            dbManager = new dbmanagerSaleInvoices("saleinvoicesForm", new RadarSaleInvoices() { isDado = this.isDado }, this);
            dbManager.AddMaster(this, VI_SaleInvoices.Name, true);
            dbManager.AddSlave(VI_SaleInvoicesDetails.Name, true);
            dbManager.AddRelation("SaleInvoicesDetails", VI_SaleInvoices.InvoiceNo, VI_SaleInvoicesDetails.InvoiceNo, true);

            formatter = new CounterFormatter();
            dRCustomer = new DRCustomer(false);
            dRItemsPrice = new DRItemsPrice();
            drItems = new DRItems();
            drTaxCode = new DRTaxCode();
            drCategories = new DRDescriptions(DescriptionType.E_Category);
            rRItemCustomerPrice = new RRItemCustomerPrice();
            dRItemCustomerPrice = new DRItemCustomerPrice();
            fncCustomer.AttachCounterType(GlobalInfo.GetCounter(Properties.Resources.CN_Customers), GlobalInfo.CurrentDate);

            if (isDado)
            {
                fncSalesNo.AttachCounterType(GlobalInfo.GetCounter(Properties.Resources.CN_Dado), GlobalInfo.CurrentDate);
                formatter.AttachCounterType(GlobalInfo.GetCounter(Properties.Resources.CN_Dado), GlobalInfo.CurrentDate);
            }
            else
            {
                fncSalesNo.AttachCounterType(GlobalInfo.GetCounter(Properties.Resources.CN_SalesInvoice), GlobalInfo.CurrentDate);
                formatter.AttachCounterType(GlobalInfo.GetCounter(Properties.Resources.CN_SalesInvoice), GlobalInfo.CurrentDate);
            }

            fncCustomer.RadarForm = new RadarCustomerForm();
            fncCustomer.DescriptionControl = txtCompany;
            rdrTitle.RadarForm = new RadarDescriptions(DescriptionType.E_Title);
            rdrTitle.DescriptionControl = lblTitleDesc;

            rrItemCat = new RRItemCategory();
            colCateg.AttachDataReader(rrItemCat, VI_ItemsPrice.Category, VI_Descriptions.Description, false);
            colCateg.AttachDescription(VI_ItemsPrice.Price);

            //colCateg.DescriptionColumn = VI_ItemCustomerPrice.DescCategory;

            clbAppearance.AttachDataReader(new RRDescriptions(DescriptionType.E_Appearance), VI_Descriptions.Code, VI_Descriptions.Description);

            colTax.AttachDataReader(new RRTaxCode(), VI_TaxCode.Code, VI_TaxCode.Description);

            cbbTransportManager = new ComboBoxManager<string>();
            cbbTransportManager.AttachDataReader(new RRDescriptions(DescriptionType.E_Transport), VI_Descriptions.Code, VI_Descriptions.Description, true);
            cbbTransportManager.AttachTo(cbbTransport);

            cbbPaymentManager = new ComboBoxManager<string>();
            cbbPaymentManager.AttachDataReader(new RRDescriptions(DescriptionType.E_Payment), VI_Descriptions.Code, VI_Descriptions.Description, true);
            cbbPaymentManager.AttachTo(cbbPayment);
        }

        protected override void OnBindData()
        {
            // Il campo chiave deve essere  NullValue.NotSet
            BindControl(fncSalesNo, VI_SaleInvoices.InvoiceNo, NullValue.NotSet, Findable.YES);
            BindObject(IsDado, VI_SaleInvoices.IsDado);

            BindControl(fncCustomer, VI_SaleInvoices.Customer, Findable.YES);
            BindControl(ctbDate, VI_SaleInvoices.ReleaseDate);
            BindControl(txtCompany, VI_SaleInvoices.Description, Findable.YES);

            BindControl(rdrTitle, VI_SaleInvoices.Title);
            BindControl(txtAddress, VI_SaleInvoices.Address);
            BindControl(mtbZip, VI_SaleInvoices.ZipCode);
            BindControl(txtCity, VI_SaleInvoices.City);
            BindControl(txtCounty, VI_SaleInvoices.County);

            BindControl(cbbDestGoods, VI_SaleInvoices.DestGoods, "SelectedValue");

            BindControl(mtbTaxNo, VI_SaleInvoices.TaxNo);
            BindControl(mtbFiscalCode, VI_SaleInvoices.FiscalCode);

            BindControl(cbbTransport, VI_SaleInvoices.Transport, "SelectedValue");
            BindControl(clbAppearance, VI_SaleInvoices.Appearance, "Value");
            BindControl(dtpTransport, VI_SaleInvoices.TransportDate);

            BindControl(cbbPayment, VI_SaleInvoices.Payment, "SelectedValue");

            BindControl(ntbLitres, VI_SaleInvoices.LitresNo);
            BindControl(ntbPieces, VI_SaleInvoices.PackagesNo);

            BindCounter(ref fncSalesNo);

            dgwDetails.AutoGenerateColumns = false;
            dgwDetails.DataSource = dbManager.SlaveBinding("SaleInvoicesDetails");

            BindColumn(colLine, VI_SaleInvoicesDetails.Line);
            BindColumn(colItem, VI_SaleInvoicesDetails.Item);
            BindColumn(colItemDesc, VI_SaleInvoicesDetails.Description);
            BindColumn(colCateg, VI_SaleInvoicesDetails.Category);
            BindColumn(colTax, VI_SaleInvoicesDetails.TaxCode);
            BindColumn(colQty, VI_SaleInvoicesDetails.Quantity);
            BindColumn(colPrice, VI_SaleInvoicesDetails.Price);
            BindColumn(colTotal, VI_SaleInvoicesDetails.Total);
            BindColumn(colLitres, VI_SaleInvoicesDetails.Litres);
            BindColumn(colLot, VI_SaleInvoicesDetails.Lot);

            dgwDetails.AddReadOnlyColumn(VI_SaleInvoicesDetails.Description, true);
            dgwDetails.AddReadOnlyColumn(VI_SaleInvoicesDetails.Total, true);
            dgwDetails.AddColumnChangeValue(VI_SaleInvoicesDetails.Item, new ExtendedDataGridView.DataGridViewValueChangeEventHandler(dgwDetails_ItemChange));
            dgwDetails.AddColumnChangeValue(VI_SaleInvoicesDetails.Category, new ExtendedDataGridView.DataGridViewValueChangeEventHandler(dgwDetails_CategoryChange));
            dgwDetails.AddColumnChangeValue(VI_SaleInvoicesDetails.Price, new ExtendedDataGridView.DataGridViewValueChangeEventHandler(dgwDetails_QtyPriceChange));
            dgwDetails.AddColumnChangeValue(VI_SaleInvoicesDetails.Quantity, new ExtendedDataGridView.DataGridViewValueChangeEventHandler(dgwDetails_QtyPriceChange));

            dgwDetails.DataGridViewRowRemoved += new DataGridViewRowsRemovedEventHandler(dgwDetails_DataGridViewRowRemoved);
            dgwDetails.DataGridViewPrepareRowEventHandler += new DataGridViewRowEventHandler(dgwDetails_DataGridViewPrepareRowEventHandler);

            dgwDetails.RowIndex = VI_SaleInvoicesDetails.Line;

            colItem.AttachCodeType("Items");
            colItem.RadarForm = new RadarItemsForm();
            colItem.DescriptionColumn = VI_SaleInvoicesDetails.Description;

            BindControl(dgwDetails);
        }

        protected override void OnDisableControlsForEdit()
        {
            fncSalesNo.Enabled = false;
            base.OnDisableControlsForEdit();
        }

        protected override void OnDisableControlsForNew()
        {
            ctbDate.Today = GlobalInfo.CurrentDate;
            dtpTransport.Value = GlobalInfo.CurrentDate;
            fncCustomer.Text = fncCustomer.EmptyCode;
            IsDado.Value = isDado;
            base.OnDisableControlsForNew();
        }

        protected override void FocusOnNew()
        {
            fncSalesNo.Focus();
        }

        protected override bool OnBeforeUndo()
        {
            return base.OnBeforeUndo();
        }

        protected override bool OnBeforeSave()
        {
            if (!FiscalCodeChecker.CheckFiscalCode(mtbFiscalCode.Text))
            {
                MyMessageBox(this, Properties.Resources.Err_FiscalCode,
                Properties.Resources.Error,
                MessageBoxButtons.OK, MessageBoxIcon.Error);

                //return false;
            }
            if (!TaxNoChecker.CheckTaxNo(mtbTaxNo.Text))
            {
                MyMessageBox(this, Properties.Resources.Err_TaxNo,
                Properties.Resources.Error,
                MessageBoxButtons.OK, MessageBoxIcon.Error);
                return false;
            }
            return base.OnBeforeSave();
        }

        protected override void OnPrepareAuxData()
        {
            foreach (DataGridViewRow dr in dgwDetails.Rows)
            {
                if (!dr.IsNewRow)
                {
                    //if (drCategories.Find(DataGridViewRowValues.GetValue<string>(dr, VI_SaleInvoicesDetails.Category)))
                    //    DataGridViewRowValues.SetValue<string>(dr, VI_SaleInvoicesDetails.DescCategory, drCategories.GetValue<string>(VI_Descriptions.Description));
                    DataGridViewRowValues.SetValue<double>(dr, VI_SaleInvoicesDetails.Total,
                                       DataGridViewRowValues.GetValue<double>(dr, VI_SaleInvoicesDetails.Quantity) *
                                       DataGridViewRowValues.GetValue<double>(dr, VI_SaleInvoicesDetails.Price));
                }
            }
            CalculateTotal();
            base.OnPrepareAuxData();
        }

        protected override void OnAddSplitMenuButton()
        {
            AddSplitPreviewButton(Properties.Resources.PRNT_INVOICE, PRINT_INVOICE, PrintType.Letter, Properties.Resources.B_Invoice);
            AddSplitPrintButton(Properties.Resources.PRNT_INVOICE, PRINT_INVOICE, PrintType.Letter, Properties.Resources.B_Invoice);
            base.OnAddSplitMenuButton();
        }

        protected override void OnCustomizeToolbar(ToolStrip toolstrip)
        {
            if (isDado)
                AddCustomButton(DELETE_INVOICE, Properties.Resources.DeleteInvoice, Properties.Resources.B_Trash, true);
            base.OnCustomizeToolbar(toolstrip);
        }

        protected override bool OnEnableToolbarButtons(ToolStripButton button)
        {
            if (button.Name == DELETE_INVOICE)
            {
                if (dbManager.Status != DBMode.Browse)
                    return false;
            }
            return base.OnEnableToolbarButtons(button);
        }

        protected override void OnCustomButtonClick(ToolStripButton button)
        {
            if (button.Name == DELETE_INVOICE)
            {
                if (MessageBox.Show(global::Vintner.Properties.Resources.Msg_DeleteInvoices,
                    global::Vintner.Properties.Resources.Warning,
                    MessageBoxButtons.YesNo, MessageBoxIcon.Warning) == System.Windows.Forms.DialogResult.Yes)
                {
                }
            }
            base.OnCustomButtonClick(button);
        }

        protected override bool OnPrintDocument(PrintInfo sender, printerForm pf)
        {
            switch (sender.ReportName)
            {
                case PRINT_INVOICE:
                    return PrintInvoice(pf);
                default:
                    return true;
            }
        }

        #endregion

        #region Events

        private void mtbFiscalCode_Validating(object sender, CancelEventArgs e)
        {
            if (!FiscalCodeChecker.CheckFiscalCode(mtbFiscalCode.Text))
            {
                MyMessageBox(this, global::Vintner.Properties.Resources.Err_FiscalCode,
                global::Vintner.Properties.Resources.Warning,
                MessageBoxButtons.OK, MessageBoxIcon.Warning);
            }
        }

        private void mtbTaxNo_Validating(object sender, CancelEventArgs e)
        {
            if (!TaxNoChecker.CheckTaxNo(mtbTaxNo.Text))
            {
                MyMessageBox(this, global::Vintner.Properties.Resources.Err_TaxNo,
                global::Vintner.Properties.Resources.Warning,
                MessageBoxButtons.OK, MessageBoxIcon.Warning);
            }
        }

        private void fncCustomer_Validating(object sender, CancelEventArgs e)
        {
            if (fncCustomer.IsEmpty)
                return;

            LoadDataCustomerInInvoice(true);
        }

        private void dgwDetails_ItemChange(object sender, DataGridViewCellEventArgs e)
        {
            // cerco se esiste un abbinamento Cliente / articolo
            string item = dgwDetails.GetValue<string>(e.RowIndex, VI_SaleInvoicesDetails.Item);

            rrItemCat.Find(item);
            colCateg.RefreshDataReader();

            drItems.Find(item);
            dgwDetails.SetValue<double>(e.RowIndex, VI_SaleInvoicesDetails.Litres, drItems.GetValue<double>(VI_Items.Size));

            if (dRItemCustomerPrice.Find(fncCustomer.Text, item))
                dgwDetails.SetValue<string>(e.RowIndex, VI_SaleInvoicesDetails.Category, dRItemCustomerPrice.GetValue<string>(VI_ItemCustomerPrice.Category));

            string category = dgwDetails.GetValue<string>(e.RowIndex, VI_SaleInvoicesDetails.Category);
            if (string.IsNullOrEmpty(category))
                return;
            // cerso se esiste un abbinamento prezzo / categoria
            if (dRItemsPrice.Find(item, category))
            {
                dgwDetails.SetValue<string>(e.RowIndex, VI_SaleInvoicesDetails.Price, dRItemsPrice.GetValue<string>(VI_ItemsPrice.Price));
                dgwDetails.SetValue<string>(e.RowIndex, VI_SaleInvoicesDetails.TaxCode, dRItemsPrice.GetValue<string>(VI_ItemsPrice.TaxCode));
            }

            CalculateTotal();
        }

        private void dgwDetails_CategoryChange(object sender, DataGridViewCellEventArgs e)
        {
            string item = dgwDetails.GetValue<string>(e.RowIndex, VI_SaleInvoicesDetails.Item);
            string category = dgwDetails.GetValue<string>(e.RowIndex, VI_SaleInvoicesDetails.Category);
            if (string.IsNullOrEmpty(item) || string.IsNullOrEmpty(category))
                return;

            // cerso se esiste un abbinamento prezzo / categoria
            if (dRItemsPrice.Find(item, category))
            {
                dgwDetails.SetValue<string>(e.RowIndex, VI_SaleInvoicesDetails.Price, dRItemsPrice.GetValue<string>(VI_ItemsPrice.Price));
                dgwDetails.SetValue<string>(e.RowIndex, VI_SaleInvoicesDetails.TaxCode, dRItemsPrice.GetValue<string>(VI_ItemsPrice.TaxCode));
            }
        }

        private void dgwDetails_QtyPriceChange(object sender, DataGridViewCellEventArgs e)
        {
            double total = dgwDetails.GetValue<double>(e.RowIndex, VI_SaleInvoicesDetails.Quantity) *
                            dgwDetails.GetValue<double>(e.RowIndex, VI_SaleInvoicesDetails.Price);
            dgwDetails.SetValue<double>(e.RowIndex, VI_SaleInvoicesDetails.Total, total);

            CalculateTotal();
        }

        private void dgwDetails_DataGridViewRowEnter(object sender, DataGridViewCellEventArgs e)
        {
            string item = dgwDetails.GetValue<string>(e.RowIndex, VI_SaleInvoicesDetails.Item);
            if (string.IsNullOrEmpty(item))
                return;

            rrItemCat.Find(item);
            colCateg.RefreshDataReader();
        }

        private void dgwDetails_DataGridViewRowRemoved(object sender, DataGridViewRowsRemovedEventArgs e)
        {
            CalculateTotal();
        }

        private void dgwDetails_DataGridViewPrepareRowEventHandler(object sender, DataGridViewRowEventArgs e)
        {
            string item = DataGridViewRowValues.GetValue<string>(e.Row, VI_SaleInvoicesDetails.Item);
            if (string.IsNullOrEmpty(item))
                return;
            drItems.Find(item);
            DataGridViewRowValues.SetValue<double>(e.Row, VI_SaleInvoicesDetails.Litres, drItems.GetValue<double>(VI_Items.Size));
        }

        #endregion

        private void CalculateTotal()
        {
            double litres = 0;
            double totalAmount = 0;
            double totalTax = 0;
            string taxCode = string.Empty, taxDesc = string.Empty;
            totals.Clear();
            foreach (DataGridViewRow dr in dgwDetails.Rows)
            {
                if (!dr.IsNewRow)
                {
                    litres += DataGridViewRowValues.GetValue<double>(dr, VI_SaleInvoicesDetails.Litres) *
                            DataGridViewRowValues.GetValue<double>(dr, VI_SaleInvoicesDetails.Quantity);

                    totalAmount = DataGridViewRowValues.GetValue<double>(dr, VI_SaleInvoicesDetails.Total);
                    taxCode = DataGridViewRowValues.GetValue<string>(dr, VI_SaleInvoicesDetails.TaxCode);
                    drTaxCode.Find(taxCode);
                    taxDesc = drTaxCode.GetValue<string>(VI_TaxCode.Description);

                    totalTax = totalAmount * drTaxCode.GetValue<double>(VI_TaxCode.Percent) / 100;

                    totals.Add(taxCode, taxDesc, totalAmount, totalTax);
                }
            }
            ntbLitres.Double = litres;

            lsvTotals.Items.Clear();

            //double totAmount = 0, totTax = 0;

            foreach (KeyValuePair<string, TaxableData> kvp in totals)
            {
                ListViewItem lvi = lsvTotals.Items.Add(kvp.Value.Amount.ToString("C"));
                lvi.SubItems.Add(kvp.Key);
                lvi.SubItems.Add(kvp.Value.Tax.ToString("C"));
                lvi.SubItems.Add((kvp.Value.Amount + kvp.Value.Tax).ToString("C"));

                //totals.totAmount += kvp.Value.Amount;
                //totals.totTax += kvp.Value.Tax;
            }
            ListViewItem lviT = lsvTotals.Items.Add("________");
            lviT.SubItems.Add("________");
            lviT.SubItems.Add("________");
            lviT.SubItems.Add("________");

            lviT = lsvTotals.Items.Add(totals.totAmount.ToString("C"));
            lviT.SubItems.Add("");
            lviT.SubItems.Add(totals.totTax.ToString("C"));
            lviT.SubItems.Add((totals.totTax + totals.totAmount).ToString("C"));

            lsvTotals.AutoResizeColumns(ColumnHeaderAutoResizeStyle.HeaderSize);
        }

        private bool PrintInvoice(printerForm pf)
        {
            DSInvoice pH = new DSInvoice();
            DSInvoice.HeaderRow dHeader = pH.Header.NewHeaderRow();
            formatter.Text = fncSalesNo.Text;
            dHeader["Prefix"] = fncSalesNo.PrefixValue + fncSalesNo.PrefixSeparator;
            dHeader["InvoiceProg"] = fncSalesNo.CounterNumericValue.ToString("0000000000".Substring(0, fncSalesNo.CounterLen));
            dHeader["InvoiceNo"] = fncSalesNo.CounterNumericValue;
            dHeader["Suffix"] = fncSalesNo.SuffixSeparator + fncSalesNo.SuffixValue;
            dHeader[VI_SaleInvoices.InvoiceNo.Name] = fncSalesNo.Text;

            dHeader[VI_SaleInvoices.ReleaseDate.Name] = ctbDate.Today;

            dHeader[VI_SaleInvoices.Title.Name] = lblTitleDesc.Text != ""
                                                    ? lblTitleDesc.Text
                                                    : "Spett.";
            string trimmedDesc = txtCompany.Text.TrimEnd(new char[] { '\r', '\n', '\t', ' ' });
            trimmedDesc = string.Concat(trimmedDesc, '\n', txtAddress.Text, "\n");
            dHeader[VI_SaleInvoices.Description.Name] = string.Concat(trimmedDesc, mtbZip.Text, " ", txtCity.Text, " ", txtCounty.Text);

            dHeader[VI_SaleInvoices.FiscalCode.Name] = mtbFiscalCode.Text;
            dHeader[VI_SaleInvoices.TaxNo.Name] = mtbTaxNo.Text;
            dHeader[VI_SaleInvoices.Payment.Name] = cbbPayment.Text;

            dHeader[VI_SaleInvoices.LitresNo.Name] = ntbLitres.Double;
            dHeader[VI_SaleInvoices.PackagesNo.Name] = ntbPieces.Int;
            dHeader[VI_SaleInvoices.DestGoods.Name] = cbbDestGoods.Text;
            dHeader[VI_SaleInvoices.Appearance.Name] = clbAppearance.Decode;
            dHeader[VI_SaleInvoices.Transport.Name] = cbbTransport.Text;
            dHeader[VI_SaleInvoices.TransportDate.Name] = dtpTransport.Value;

            dHeader["Total"] = totals.totAmount + totals.totTax;

            pH.Header.AddHeaderRow(dHeader);

            foreach (DataGridViewRow dr in dgwDetails.Rows)
            {
                if (!dr.IsNewRow)
                {
                    DSInvoice.RowRow dRow = pH.Row.NewRowRow();

                    dRow[VI_SaleInvoicesDetails.InvoiceNo.Name] = fncSalesNo.Text;
                    dRow[VI_SaleInvoicesDetails.Line.Name] = DataGridViewRowValues.GetValue<int>(dr, VI_SaleInvoicesDetails.Line);
                    dRow[VI_SaleInvoicesDetails.Item.Name] = DataGridViewRowValues.GetValue<string>(dr, VI_SaleInvoicesDetails.Item);
                    dRow[VI_SaleInvoicesDetails.Description.Name] = DataGridViewRowValues.GetValue<string>(dr, VI_SaleInvoicesDetails.Description);
                    dRow[VI_SaleInvoicesDetails.Price.Name] = DataGridViewRowValues.GetValue<string>(dr, VI_SaleInvoicesDetails.Price);
                    dRow[VI_SaleInvoicesDetails.Quantity.Name] = DataGridViewRowValues.GetValue<string>(dr, VI_SaleInvoicesDetails.Quantity);
                    drTaxCode.Find(DataGridViewRowValues.GetValue<string>(dr, VI_SaleInvoicesDetails.TaxCode));
                    dRow[VI_SaleInvoicesDetails.TaxCode.Name] = drTaxCode.GetValue<string>(VI_TaxCode.Description);
                    pH.Row.AddRowRow(dRow);
                }
            }

            foreach (KeyValuePair<string, TaxableData> kvp in totals)
            {
                DSInvoice.TaxRow dTax = pH.Tax.NewTaxRow();

                dTax["SaleNo"] = fncSalesNo.Text;
                dTax["Amount"] = kvp.Value.Amount;
                dTax["TaxCode"] = kvp.Value.Desc;
                dTax["TaxAmount"] = kvp.Value.Tax;
                pH.Tax.AddTaxRow(dTax);
            }

            pf.SetParameterValue("IsDado", isDado);
            pf.ShowReport(new PrintSales(), pH);
            return true;
        }

        protected void LoadDataCustomerInInvoice(bool includePrice)
        {
            dRCustomer.Find(fncCustomer.Text);

            txtCompany.Text = dRCustomer.GetValue<string>(VI_Customers.Description);
            txtAddress.Text = dRCustomer.GetValue<string>(VI_Customers.Address);
            txtCity.Text = dRCustomer.GetValue<string>(VI_Customers.City);
            txtCounty.Text = dRCustomer.GetValue<string>(VI_Customers.County);
            mtbZip.Text = dRCustomer.GetValue<string>(VI_Customers.ZipCode);
            mtbTaxNo.Text = dRCustomer.GetValue<string>(VI_Customers.TaxNo);
            mtbFiscalCode.Text = dRCustomer.GetValue<string>(VI_Customers.FiscalCode);
            rdrTitle.Text = dRCustomer.GetValue<string>(VI_Customers.Title);

            cbbDestGoods.Items.Clear();
            if (!string.IsNullOrEmpty(dRCustomer.GetValue<string>(VI_Customers.DestGoods1)))
                cbbDestGoods.Items.Add(dRCustomer.GetValue<string>(VI_Customers.DestGoods1));
            if (!string.IsNullOrEmpty(dRCustomer.GetValue<string>(VI_Customers.DestGoods2)))
                cbbDestGoods.Items.Add(dRCustomer.GetValue<string>(VI_Customers.DestGoods2));

            if (cbbDestGoods.Items.Count > 0)
                cbbDestGoods.Text = cbbDestGoods.Items[0].ToString();

            if (!includePrice)
                return;

            colItem.Clear();
            rRItemCustomerPrice.Find(fncCustomer.Text);
            for (int t = 0; t < rRItemCustomerPrice.Count; t++)
                colItem.AddElement(rRItemCustomerPrice.GetValue<string>(VI_ItemCustomerPrice.Item, t),
                                   rRItemCustomerPrice.GetValue<string>(VI_ItemCustomerPrice.Description, t));
        }

        private bool SaleInvoices_OnEnableToolbarSplitButtons(ToolStripSplitButton sender)
        {
            return true;
        }

        internal class TaxableData
        {
            public double Amount { get; set; }

            public double Tax { get; set; }

            public string Desc { get; set; }

            public TaxableData(string desc, double amount, double tax)
            {
                Amount = amount;
                Tax = tax;
                Desc = desc;
            }
        }

        internal class TotalTaxable : SortedDictionary<string, TaxableData>
        {
            public new void Clear()
            {
                base.Clear();
                totAmount = 0;
                totTax = 0;
            }

            public double totAmount, totTax;

            public void Add(string taxCode, string desc, double amount, double tax)
            {
                totAmount += amount;
                totTax += tax;
                if (!ContainsKey(taxCode))
                    Add(taxCode, new TaxableData(desc, amount, tax));
                else
                {
                    this[taxCode].Amount += amount;
                    this[taxCode].Tax += tax;
                }
            }
        }
    }

    #region DbManager SaleInvoices

    /// <summary>
    /// Classe derivata per gestioni particolari
    /// </summary>
    internal class dbmanagerSaleInvoices : DBManager
    {
        public dbmanagerSaleInvoices(string name, RadarForm radar, DocumentForm document)
            : base(name, radar, document)
        {
            ForeignKey = VI_SaleInvoices.InvoiceNo;
        }

        protected override string CreateMasterQuery()
        {
            this.Table = new VI_SaleInvoices();
            QueryBuilder qB = new QueryBuilder();
            qB.AddSelect();
            qB.AddFrom(VI_SaleInvoices.Name);
            qB.AddCompare(VI_SaleInvoices.InvoiceNo, "@p1");

            return qB.Query;
        }

        protected override List<SqlABParameter> CreateMasterParam()
        {
            List<SqlABParameter> PList = new List<SqlABParameter>();

            SqlABParameter sParam = new SqlABParameter("@p1", VI_SaleInvoices.InvoiceNo);
            sParam.Value = VI_SaleInvoices.InvoiceNo.DefaultValue;
            PList.Add(sParam);
            return PList;
        }

        protected override void SetParameters(IRadarParameters key, DBCollection collection)
        {
            //if (collection.Name == VI_SaleInvoices.Name)
            collection.Parameter[0].Value = key[0];
        }

        protected override void dAdapter_RowUpdating(object sender, SqlABRowUpdatingEventArgs e)
        {
            if (e.StatementType == StatementType.Insert)
            {
                e.Row[VI_SaleInvoicesDetails.InvoiceNo.Name] = GetColumn<string>(VI_SaleInvoices.InvoiceNo, Pos);
                e.Row[VI_SaleInvoicesDetails.IsDado.Name] = GetColumn<string>(VI_SaleInvoices.IsDado, Pos);
            }

            base.dAdapter_RowUpdating(sender, e);
        }

        protected override string CreateSlaveQuery(string name)
        {
            if (name == VI_SaleInvoicesDetails.Name)
            {
                QueryBuilder qB = new QueryBuilder();
                qB.AddSelect();
                qB.AddFrom(VI_SaleInvoicesDetails.Name);
                qB.AddCompare(VI_SaleInvoicesDetails.InvoiceNo, "@p2");
                qB.AddOrder(VI_SaleInvoicesDetails.Line);
                return qB.Query;
            }
            return "";
        }

        protected override List<SqlABParameter> CreateSlaveParam(string name)
        {
            if (name == VI_SaleInvoicesDetails.Name)
            {
                List<SqlABParameter> PList = new List<SqlABParameter>();

                SqlABParameter sParam = new SqlABParameter("@p2", VI_SaleInvoicesDetails.InvoiceNo);
                sParam.Value = "";
                PList.Add(sParam);
                return PList;
            }
            return null;
        }
    }

    #endregion

    public class DadoSaleInvoices : SaleInvoices
    {
        public DadoSaleInvoices()
            : base()
        {
            isDado = true;
            Text = "Dado Fattura";
        }
    }
}